import time

from appium.webdriver.common.touch_action import TouchAction
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException

from common.find_img import FindImg
from common.report_add_img import add_img_2_report
from common.tools import get_project_path, build_path
from logs.log import get_log

# 创建日志记录器
logger = get_log("自动化测试")


class Base:

    def find_element_new(self, driver, locator_type, locator_value, timeout=10):
        """
        等待直到指定的元素出现，如果元素未找到则返回 None 并继续。
        """
        try:
            logger.info(f"正在查找元素: {locator_type} - {locator_value}")
            element = WebDriverWait(driver, timeout).until(
                EC.presence_of_element_located((locator_type, locator_value))
            )
            return element
        except (TimeoutException, NoSuchElementException):
            logger.warning(f"元素未找到: {locator_type}, {locator_value}")
            return None

    def find_elements_new(self, driver, locator_type, locator_value, timeout=10):
        """
        等待直到指定的元素数组出现。
        """
        try:
            logger.info(f"正在查找元素数组: {locator_type} - {locator_value}")
            elements = WebDriverWait(driver, timeout).until(
                EC.presence_of_all_elements_located((locator_type, locator_value))
            )
            return elements
        except (TimeoutException, NoSuchElementException):
            logger.warning(f"元素数组未找到: {locator_type}, {locator_value}")
            return None

    def send_keys_new(self, driver, locator_type, locator_value, value, timeout=10):
        """
        在文本框中输入内容。
        """
        try:
            logger.info(f"在元素 {locator_type, locator_value} 中输入内容: {value}")
            element = self.find_element_new(driver, locator_type, locator_value, timeout)
            element.clear()
            element.send_keys(value)
        except Exception as e:
            logger.error(f"在元素 {locator_type, locator_value} 中输入内容失败: {str(e)}")

    def click_new(self, driver, locator_type, locator_value, timeout=10):
        """
        点击按钮。
        """
        try:
            logger.info(f"点击元素: {locator_type} - {locator_value}")
            element = self.find_element_new(driver, locator_type, locator_value, timeout)
            element.click()
        except Exception as e:
            logger.error(f"点击元素 {locator_type, locator_value} 失败: {str(e)}")

    def swipe_up_new(self, driver, locator_type, locator_value, timeout=30, duration=1000):
        """
        向上滑动屏幕。
        """
        try:
            logger.info(f"正在向上滑动屏幕，目标元素: {locator_type} - {locator_value}")
            WebDriverWait(driver, timeout).until(
                EC.presence_of_element_located((locator_type, locator_value))
            )

            screen_size = driver.get_window_size()
            width = screen_size['width']
            height = screen_size['height']

            start_x = width / 2
            start_y = height * 0.8
            end_x = width / 2
            end_y = height * 0.2

            action = TouchAction(driver)
            action.press(x=start_x, y=start_y).wait(duration).move_to(x=end_x, y=end_y).release().perform()
            logger.info("滑动成功")
            return True
        except Exception as e:
            logger.error(f"向上滑动失败: {str(e)}")
            return False

    def get_text(self, driver, locator_type, locator_value):
        """
        获取元素的文本值。
        """
        element = self.find_element_new(driver, locator_type, locator_value)
        try:
            element_text = element.text
            logger.info(f"获取到的文本: {element_text}")
            return element_text
        except Exception as e:
            logger.error(f"元素text获取失败，错误信息为：{str(e)}")

    def find_img_in_source(self, driver, img_name):
        """
        截图并在截图中查找图片
        """
        search_img_path = get_project_path() + build_path("img", "assert_img", img_name, add_sep_before=True)
        source_img_path = get_project_path() + build_path("img", "source_img", img_name, add_sep_before=True)

        driver.get_screenshot_as_file(source_img_path)
        time.sleep(3)
        logger.info(f"在截图中查找图片: {img_name}")

        confidence = FindImg().get_confidence(source_img_path, search_img_path)
        logger.info(f"找到图片的信心值为: {confidence}")
        return confidence


class BaseAssert:
    def assert_equal_screen_shot(self, driver, exceptor, step_name):
        """
        比较屏幕截图和预期图像，进行断言。
        """
        if not isinstance(exceptor, tuple):
            logger.error('exceptor参数类型错误，必须传元组类型')
        else:
            logger.info(f"正在断言: {exceptor[0]} 是否等于 {exceptor[1]}")
            try:
                assert exceptor[0] == exceptor[1]
                add_img_2_report(driver, step_name=step_name)
            except Exception as e:
                logger.error(f"断言失败: {str(e)}")
                add_img_2_report(driver, step_name=step_name)
                raise e